'use strict';

const db = uniCloud.database();
const dbcmd = db.command;

exports.main = async (event, context) => {
	let response = {
		code: 0,
		datas: {
			cancel: {
				count: 0
			},
			group: {
				count: 0
			}
		}
	};
	const ip = context.CLIENTIP;
	const orderParameterRes = await db.collection('usemall-order-parameter')
		.field({
			overdue_minute_cancel_order: true
		})
		.limit(1)
		.get();
	const [orderParameter] = orderParameterRes.data;

	// 待付款 下单后，超过多少分钟未付款自动取消订单
	response.datas.cancel.count = await doCancelOrder(ip, orderParameter);
	
	try {
		// 待成团 已到期待成团订单，拼单成功|失败
		response.datas.group.count = await doGroupOrder(ip);
	} catch(e) {
		console.log('doGroupOrder err', e);
	}
	
	console.log('res', response);
	
	//返回数据给客户端
	return response;
};

// 待付款 下单后，超过多少分钟未付款自动取消订单
const doCancelOrder = async (ip, orderParameter) => {
	const cancelOrderTime = orderParameter.overdue_minute_cancel_order || 30;
	let count = 0;
	let cancelRes = {};
	do {
		// 取消订单
		cancelRes = await cancelOrder(ip, cancelOrderTime);
		count += cancelRes.count;
	} while (cancelRes.count >= 300)
	
	return count;
}
/**
 * 取消订单
 * 
 * 1. 超时订单，更改为已取消
 * 2. 写入订单日志
 * 3. 判断是否需要释放库存
 * 4. 判断是否需要释放优惠券
 */ 
const cancelOrder = async (ip, cancelOrderTime = 30) => {
	const nowdate = Date.now();
	const res = {
		count: 0
	};
	const orderRes = await db.collection('usemall-order')
		.where({
			state: '待付款',
			create_time: dbcmd.lte(nowdate - cancelOrderTime * 60 * 1000)
		})
		.field({
			order_id: true,
			order_coupon_id: true,
			order_ded_stock: true
		})
		.limit(300)
		.get();

	if (orderRes.data && orderRes.data.length > 0) {
		res.count = orderRes.data.length;

		const orderIds = [];
		const orderLogs = [];
		
		const stockOrderIds = [];
		
		let couponIds = [];
		let couponUids = [];
		let couponRuleIds = [];
		
		orderRes.data.forEach((order) => {
			orderIds.push(order.order_id);
			orderLogs.push({
				order_id: order.order_id,
				log_type: '取消订单',
				remark: `待付款订单超过 ${cancelOrderTime} 分钟未支付订单自动取消`,
				current_state: '已取消',
				prev_state: '待付款',
				ip: ip,
				is_delete: 0,
				create_uid: 'job',
				create_time: nowdate
			});
			
			// 已扣减库存
			if (order.order_ded_stock) {
				stockOrderIds.push(order.order_id);
			}
			
			// 已使用优惠券
			if (order.order_coupon_id) {
				couponIds.push(order.order_coupon_id);
			}
		});

		// 1. 超时订单，更改为已取消
		res.updateRes = await db.collection('usemall-order')
			.where({
				order_id: dbcmd.in(orderIds)
			})
			.update({
				state: '已取消',
				last_modify_time: nowdate,
				last_modify_uid: 'job',
			})
			
		// 2. 写入订单日志
		res.addLogRes = await db.collection('usemall-order-log').add(orderLogs);
		
		// 3. 释放库存
		if (stockOrderIds && stockOrderIds.length) {
			// 查询订单详情
			const orderDetailRes = await db.collection('usemall-order-detail').where({
					order_id: dbcmd.in(stockOrderIds)
				})
				.field({
					goods_id: true,
					goods_sku: true,
					goods_num: true,
				})
				.get();
			
			for (let i = 0; i < orderDetailRes.data.length; i++) {
				let x = orderDetailRes.data[i];
			
				// 释放库存
				await db.collection('usemall-goods')
					.doc(x.goods_id)
					.update({
						stock_num: dbcmd.inc(x.goods_num),
						sale_cnt: dbcmd.inc(-x.goods_num)
					});
				// 释放SKU库存
				if (x.goods_sku) {
					await db.collection('usemall-goods-sku')
						.where({
							goods_id: x.goods_id,
							goods_sku: x.goods_sku
						})
						.update({
							stock_num: dbcmd.inc(x.goods_num),
							sale_cnt: dbcmd.inc(-x.goods_num)
						});
				}
			}
		}
		
		// 4. 释放优惠券
		if (couponIds && couponIds.length) {
			// 获取对应的优惠券数据
			const couponRes = await db.collection('usemall-marketing-coupon')
				.where({
					_id: dbcmd.in(couponIds)
				})
				.get();
			if (couponRes.data && couponRes.data.length) {
				// 优惠券领取人 ids
				couponUids = couponRes.data.map(x => x.member_id);
				// 优惠券规则 ids
				couponRuleIds = couponRes.data.map(x => x.coupon_id);
			}
			
			if (couponIds.length) {
				await db.collection('usemall-marketing-coupon')
					.where({
						_id: dbcmd.in(couponIds)
					})
					.update({
						last_modify_time: nowdate,
						last_modify_uid: 'job',
				
						version: dbcmd.inc(1),
				
						state: "已领取"
					});
			}
			
			if (couponRuleIds.length) {
				await db.collection('usemall-marketing-coupon-rule')
					.where({
						_id: dbcmd.in(couponRuleIds)
					})
					.update({
						use_num: dbcmd.inc(-1),
						version: dbcmd.inc(1)
					});
			}
				
			if (couponUids.length) {
				await db.collection('usemall-member')
					.where({
						_id: dbcmd.in(couponUids)
					})
					.update({
						member_coupon_cnt: dbcmd.inc(1)
					});
			}
		}
		
	}

	return res;
}


// 待成团 已到期待成团订单，拼单成功|失败
const doGroupOrder = async (ip) => {
	let count = 0;
	let res = {};
	do {
		// 拼团订单
		res = await groupOrder(ip);
		count += res.count;
	} while (res.count >= 100)
	
	return count;
}
const groupOrder = async (ip) => {
	const nowdate = Date.now();
	const res = {
		count: 0
	};
	const orderRes = await db.collection('usemall-order')
		.where({
			state: '待成团',
			order_expire_time: dbcmd.lt(nowdate)
		})
		.field({
			order_actural_paid: true,
			order_id: true,
			order_type: true,
			order_member_name: true,
			order_member_openid: true,
			order_member_headimg: true,
			order_info: true,
			order_goods_cnt: true,
			create_uid: true,
			state: true,
			order_ded_stock: true,
			
			seckill_id: true,
			group_id: true,
			group_chief_id: true
		})
		.limit(100)
		.get();

	if (orderRes.data && orderRes.data.length) {
		res.count = orderRes.data.length;

		for (let i = 0; i < orderRes.data.length; i++) {
			let order = orderRes.data[i];
			// 拼团订单
			// 判断是否已成团
			// 	拼团成功
			// 		1. 修改参团表（状态、已付款数）
			// 		2. 修改订单表（待发货）
			// 	拼团失败
			//		1. 修改参团表（状态、已付款数)
			//		2. 修改订单表
			// 拼团表（参团人、参团人数、参团订单数）
			
			let orderUpdateObj = {};
			let groupMemberUpdateObj = {};
			
			let groupData = {};
			let groupChiefData = {};
			if (order.group_id) {
				try {
					// false 不验证活动是否已结束或已过期
					groupData = await getGroup(order.group_id, false);
					
					if (order.group_chief_id) {
						// 获取参团数据
						groupChiefData = await getGroupChief(order.group_chief_id, false);
					} else {
						// 获取订单团购数据
						groupChiefData = await getGroupChiefByOrder(order.order_id, false);
					}
				} catch(e) {
					console.log('group order', { group_id: order.group_id, group_chief_id: order.group_chief_id, order_id: order.order_id });
					console.log('group order err', e);
					
					// 处理下一条
					continue;
				}
			}
			
			// 拼团订单
			if (groupData && groupData._id) {
				if (groupChiefData.group_member_pay_cnt >= groupData.group_num) {
					// 拼团成功
					
					// 1. 修改拼团状态 state 已成团
					// 2. 修改所有参团人员的订单状态 state 待发货
					// 3. 记录对应的订单日志
					
					// 成团时间
					orderUpdateObj.order_group_time = nowdate;
					// 订单状态
					orderUpdateObj.state = '待发货';
					groupMemberUpdateObj.state = '已成团';
					
					// 拼团表（成团数）
					await db.collection('usemall-market-groupbuy').doc(groupData._id).update({
						version: dbcmd.inc(1),
						group_success_num: dbcmd.inc(1),
						
						last_modify_uid: 'job',
						last_modify_uname: 'job',
						last_modify_time: nowdate
					});
				} else {
					// 拼团失败
					
					// 1. 修改拼团状态 state 已失败
					// 2. 修改所有参团人员的订单状态 state 已取消
					// 3. 记录对应的订单日志
					
					// 订单状态
					orderUpdateObj.state = '已取消';
					// 已失败
					groupMemberUpdateObj.state = '已失败';
					
					// 处理退款逻辑，1小时左右自动退款
					orderUpdateObj.order_refund_state = '待退款';
				}
				
				// 修改参团表
				await db.collection('usemall-market-groupbuy-member').doc(groupChiefData._id).update({
					last_modify_uid: 'job',
					last_modify_time: nowdate,
					last_modify_uname: 'job',
					
					...groupMemberUpdateObj
				});
				
				// 更改订单状态
				const orderUpdateRes = await db.collection('usemall-order').where({
					order_id: order.order_id,
					state: '待成团'
				}).update({
					last_modify_time: nowdate,
					last_modify_uid: 'job',
					last_modify_uname: 'job',
					
					version: dbcmd.inc(1),
					
					...orderUpdateObj
				});
				
				if (orderUpdateRes.updated) {
					// 订单日志
					await db.collection('usemall-order-log').add({
						order_id: order.order_id,
						log_type: orderUpdateObj.state == '待发货' ? '拼单成功' : '拼单失败',
						current_state: orderUpdateObj.state,
						prev_state: '待成团',
						ip: '',
						is_delete: 0,
						create_uid: 'job',
						create_time: nowdate
					});
					
					if (orderUpdateObj.state == '已取消') {
						// 释放库存
						if (order.order_ded_stock) {
							// 查询订单详情
							const orderDetailRes = await db.collection('usemall-order-detail').where({
									order_id: order.order_id
								})
								.field({
									goods_id: true,
									goods_sku: true,
									goods_num: true,
								})
								.get();
							
							for (let d = 0; d < orderDetailRes.data.length; d++) {
								let x = orderDetailRes.data[d];
							
								// 释放库存
								await db.collection('usemall-goods')
									.doc(x.goods_id)
									.update({
										stock_num: dbcmd.inc(x.goods_num),
										sale_cnt: dbcmd.inc(-x.goods_num)
									});
								// 释放SKU库存
								if (x.goods_sku) {
									await db.collection('usemall-goods-sku')
										.where({
											goods_id: x.goods_id,
											goods_sku: x.goods_sku
										})
										.update({
											stock_num: dbcmd.inc(x.goods_num),
											sale_cnt: dbcmd.inc(-x.goods_num)
										});
								}
							}
						}
					}
				}
				
			}
		}
	}

	return res;
}


/**
 * 根据拼团活动ID获取数据
 * verify 验证活动是否有效
 */
async function getGroup(id, verify = true) {
	const groupRes = await db.collection('usemall-market-groupbuy').doc(id).field({
		goods_id: true,
		goods_obj: true,
		goods_price: true,
		group_num: true,
		group_members: true,
		group_begin_time: true,
		group_end_time: true,
		group_time: true,
		state: true,
		is_delete: true
	}).get();
	
	const [group] = groupRes.data;
	if (!(group && group._id)) {
		if (verify) {
			throw new Error(`拼团活动不存在`);
		}
		
		return {
			_id: id,
			group_num: 99999
		}
	} 
	
	// 验证活动是否有效
	if (verify) {
		const nowdate = Date.now();
		if (!(group.is_delete == 0 && group.state == '启用')) throw new Error(`拼团活动已停止`);
		if (!(group.group_begin_time <= nowdate && group.group_end_time >= nowdate)) throw new Error(`拼团活动已结束`);
		
		// 活动到期时间
		group.expires_time = (group.group_end_time - nowdate) / 1000;
	}
	
	return group;
}

/**
 * 根据拼团活动团长ID获取数据
 * verify 验证是否过期
 */
async function getGroupChief(id, verify = true) {
	const groupRes = await db.collection('usemall-market-groupbuy-member').doc(id).get();
	
	const [group] = groupRes.data;
	if (!(group && group._id)) throw new Error(`当前拼单不存在`);
	
	if (group.is_delete == 1) throw new Error(`当前拼单已停止`);
	if (verify) {
		if (group.state == '已取消') throw new Error(`当前拼单活动已取消`);
		if (group.expire_time && Date.now() > group.expire_time) throw new Error(`拼单活动已结束`);
	}
	
	return group;
}

/**
 * 根据拼团活动订单ID获取数据
 * verify 验证是否过期
 */
async function getGroupChiefByOrder(id, verify = true) {
	const groupRes = await db.collection('usemall-market-groupbuy-member').where({ order_id: id }).limit(1).get();
	
	const [group] = groupRes.data;
	if (!(group && group._id)) throw new Error(`您的开团不存在`);
	
	if (group.is_delete == 1) throw new Error(`您的开团已停止`);
	if (verify) {
		if (group.state == '已取消') throw new Error(`您的开团已取消`);
		if (group.expire_time && Date.now() > group.expire_time) throw new Error(`拼单活动已结束`);
	}
	
	return group;
}

